home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / kant-generator-04-c / Kant ƒ / Shell ƒ / graphics.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  14.6 KB  |  459 lines  |  [TEXT/MMCC]

  1. #include "graphics.h"
  2. #include "about.h"
  3. #include "about MSG.h"
  4. #include "help.h"
  5. //#include "progress.h"
  6. #include "dialogs.h"
  7. #include "error.h"
  8. #include "menus.h"
  9. #include "environment.h"
  10. #include "prefs.h"
  11. #include "util.h"
  12. #include "program globals.h"
  13.  
  14. /* internal global variables for use by graphics.c only */
  15. static    ExtendedWindowDataHandle    gTheWindowData[NUM_WINDOWS];
  16. static    Rect        gBoundsRect[NUM_WINDOWS];        /* rectangle of offscreen bitmap */
  17. static    Rect        gMainScreenBounds;                /* bounds of main monitor */
  18. static    GWorldPtr    gTheGWorld[NUM_WINDOWS];        /* offscreen graphics world */
  19. static    Ptr            gBWBitMap[NUM_WINDOWS];            /* offscreen bitmap for B/W machines */
  20. static    GrafPort    gBWGrafPort[NUM_WINDOWS];        /* offscreen grafport "  "     "     */
  21. static    GrafPtr        gBWGrafPtr[NUM_WINDOWS];        /* offscreen grafptr  "  "     "     */
  22.  
  23. Boolean InitTheGraphics(void)
  24. {
  25.     short            i,j;
  26.     
  27.     GetMainScreenBounds();
  28.     
  29.     for (i=0; i<NUM_WINDOWS; i++)
  30.     {
  31.         /* nothing is inited; if there's an error later on, we'll know how much to */
  32.         /* clean up in ShutDownTheGraphics() */
  33.         gTheGWorld[i]=(GWorldPtr)0L;
  34.         gTheWindowData[i]=(ExtendedWindowDataHandle)0L;
  35.     }
  36.     
  37.     for (i=0; i<NUM_WINDOWS; i++)
  38.     {
  39.         gTheWindowData[i]=(ExtendedWindowDataHandle)NewHandle(sizeof(ExtendedWindowDataRec));
  40.         if (gTheWindowData[i]==0L)                            /* return if error */
  41.             return FALSE;
  42.         
  43.         (**(gTheWindowData[i])).offscreenNeedsUpdate=TRUE;    /* offscreen not inited */
  44.         (**(gTheWindowData[i])).theWindowPtr=0L;            /* window ptr not inited */
  45.         (**(gTheWindowData[i])).windowIndex=i;                /* so we can retrieve it O(1) */
  46.         (**(gTheWindowData[i])).windowDepth=
  47.             (**(gTheWindowData[i])).maxDepth=1;                /* init at B/W */
  48.         (**(gTheWindowData[i])).isColor=FALSE;                /* init to grayscale */
  49.         (**(gTheWindowData[i])).topLeftInitted=FALSE;        /* window pos not initted */
  50.         for (j=0; j<MAX_TE_HANDLES; j++)
  51.             (**(gTheWindowData[i])).hTE[j]=0L;
  52.         HLockHi((Handle)gTheWindowData[i]);
  53.     }
  54.     
  55.     /* set window dispatch routines */
  56.     SetIndDispatchProc(kAboutWindow, AboutBoxDispatch);
  57.     SetIndDispatchProc(kAboutMSGWindow, AboutMSGBoxDispatch);
  58. //    SetIndDispatchProc(kProgressWindow, ProgressWindowDispatch);
  59.     SetIndDispatchProc(kHelpWindow, HelpWindowDispatch);
  60.     
  61.     /* call window dispatch routines with "startup" message */
  62.     CallIndDispatchProc(kAboutWindow, kStartup, 0L);
  63.     CallIndDispatchProc(kAboutMSGWindow, kStartup, 0L);
  64. //    CallIndDispatchProc(kProgressWindow, kStartup, 0L);
  65.     CallIndDispatchProc(kHelpWindow, kStartup, 0L);
  66.     
  67.     return TRUE;
  68. }
  69.  
  70. void ShutDownTheGraphics(void)
  71. {
  72.     short            i;
  73.     ExtendedWindowDataHandle    theData;
  74.     
  75.     /* send shutdown messages to the shell's windows */
  76.     CallIndDispatchProc(kAboutWindow, kShutdown, 0L);
  77.     CallIndDispatchProc(kAboutMSGWindow, kShutdown, 0L);
  78. //    CallIndDispatchProc(kProgressWindow, kShutdown, 0L);
  79.     CallIndDispatchProc(kHelpWindow, kShutdown, 0L);
  80.     
  81.     for (i=0; i<NUM_WINDOWS; i++)
  82.     {
  83.         KillOffscreen(i);
  84.         if ((theData=GetWindowDataHandle(i))!=0L)
  85.         {
  86.             if (IndWindowExistsQQ(i))
  87.                 DisposeWindow(GetIndWindowPtr(i));
  88.             DisposeHandle((Handle)theData);
  89.         }
  90.     }
  91. }
  92.  
  93. OSErr OpenTheIndWindow(short index)
  94. {
  95.     WindowPtr        theWindow;
  96.     Point            topLeft;
  97.     Boolean            justCenteredIt;
  98.     OSErr            memError;
  99.     
  100.     if (!IndWindowExistsQQ(index))
  101.     {
  102.         justCenteredIt=FALSE;
  103.         
  104.         if (CallIndDispatchProc(index, kInitialize, 0L)==kFailure)
  105.         {        /* default is to center window on main screen */
  106.             if (!GetIndWindowPosInitted(index))
  107.             {
  108.                 topLeft=GetIndWindowPos(index);
  109.                 topLeft.h=gMainScreenBounds.left + (((gMainScreenBounds.right -
  110.                     gMainScreenBounds.left) - (**(gTheWindowData[index])).windowWidth) / 2);
  111.                 topLeft.v=gMainScreenBounds.top + (((gMainScreenBounds.bottom -
  112.                     gMainScreenBounds.top) - (**(gTheWindowData[index])).windowHeight) / 2);
  113.                 SetIndWindowPos(index, topLeft);
  114.                 justCenteredIt=TRUE;
  115.             }
  116.         }
  117.         
  118.         topLeft=GetIndWindowPos(index);
  119.         (**(gTheWindowData[index])).windowBounds.left=topLeft.h;
  120.         (**(gTheWindowData[index])).windowBounds.top=topLeft.v;
  121.             
  122.         if (justCenteredIt)
  123.             if (((**(gTheWindowData[index])).windowType==noGrowDocProc) ||
  124.                 ((**(gTheWindowData[index])).windowType==documentProc) ||
  125.                 ((**(gTheWindowData[index])).windowType==movableDBoxProc) ||
  126.                 ((**(gTheWindowData[index])).windowType==zoomDocProc) ||
  127.                 ((**(gTheWindowData[index])).windowType==zoomNoGrow) ||
  128.                 ((**(gTheWindowData[index])).windowType==rDocProc))
  129.                     (**(gTheWindowData[index])).windowBounds.top += 9;    /* compensate for title */
  130.         
  131.         /* don't put window over menu bar */
  132.         if ((**(gTheWindowData[index])).windowBounds.top < GetMBarHeight()+1)
  133.             (**(gTheWindowData[index])).windowBounds.top = GetMBarHeight()+1;
  134.         
  135.         (**(gTheWindowData[index])).windowBounds.bottom =
  136.             (**(gTheWindowData[index])).windowBounds.top +
  137.             (**(gTheWindowData[index])).windowHeight;
  138.         
  139.         (**(gTheWindowData[index])).windowBounds.right =
  140.             (**(gTheWindowData[index])).windowBounds.left +
  141.             (**(gTheWindowData[index])).windowWidth;
  142.         
  143.         KillOffscreen(index);        /* kill offscreen bitmaps that are left over */
  144.         
  145.         if (gHasColorQD)
  146.         {
  147.             /* create the color window with our specs, see IM Essentials 4-79ff */
  148.             (**gTheWindowData[index]).theWindowPtr=
  149.                 NewCWindow(0L, &((**(gTheWindowData[index])).windowBounds),
  150.                 (**(gTheWindowData[index])).windowTitle, FALSE,
  151.                 (**(gTheWindowData[index])).windowType, (WindowPtr)-1L,
  152.                 (**(gTheWindowData[index])).hasCloseBox,
  153.                 (unsigned long)gTheWindowData[index]);
  154.         }
  155.         else
  156.         {
  157.             /* create the B/W window with our specs, see IM Essentials 4-82ff */
  158.             (**gTheWindowData[index]).theWindowPtr=
  159.                 NewWindow(0L, &((**(gTheWindowData[index])).windowBounds),
  160.                 (**(gTheWindowData[index])).windowTitle, FALSE,
  161.                 (**(gTheWindowData[index])).windowType, (WindowPtr)-1L,
  162.                 (**(gTheWindowData[index])).hasCloseBox,
  163.                 (unsigned long)gTheWindowData[index]);
  164.         }
  165.         
  166.         memError=MemError();
  167.     }
  168.     
  169.     if (IndWindowExistsQQ(index))
  170.     {
  171.         theWindow=GetIndWindowPtr(index);
  172.         ShowWindow(theWindow);            /* immediately show this new window */
  173.         SelectWindow(theWindow);        /* immediately select this new window */
  174.         SetPort(theWindow);                /* important! for TE info to stick*/
  175.         InvalRect(&(theWindow->portRect));
  176.         /* call window's dispatch routine to alert it that it's open now */
  177.         CallIndDispatchProc(index, kOpen, 0L);
  178.     }
  179.     else return memError;
  180.     
  181.     return noErr;
  182. }
  183.  
  184. void GetMainScreenBounds(void)
  185. {
  186.     gMainScreenBounds = qd.screenBits.bounds;        /* low-mem global */
  187.     gMainScreenBounds.top += GetMBarHeight();    /* don't include menu bar */
  188. }
  189.  
  190. short GetBiggestDeviceDepth(ExtendedWindowDataHandle theData)
  191. {
  192.     Rect            tempRect;
  193.     long            biggestSize;
  194.     long            tempSize;
  195.     GDHandle        thisHandle, gBiggestDevice;
  196.     
  197.     if (!gHasColorQD)
  198.         return 1;
  199.     
  200.     if (!WindowExistsQQ(theData))
  201.         return (**(**GetMainDevice()).gdPMap).pixelSize;
  202.     
  203.     thisHandle = GetDeviceList();
  204.     gBiggestDevice = 0L;
  205.     biggestSize = 0L;
  206.     
  207.     while (thisHandle)
  208.     {
  209.         if (TestDeviceAttribute(thisHandle, screenDevice) &&
  210.             TestDeviceAttribute(thisHandle, screenActive))
  211.         {
  212.             if (SectRect(&(GetWindowPtr(theData)->portRect),
  213.                     &((**thisHandle).gdRect), &tempRect))
  214.             {
  215.                 if (biggestSize < (tempSize = ((long)(tempRect.bottom - tempRect.top))*
  216.                     ((long)(tempRect.right - tempRect.left))))
  217.                 {
  218.                     biggestSize = tempSize;
  219.                     gBiggestDevice = thisHandle;
  220.                 }
  221.             }
  222.         }
  223.         thisHandle = GetNextDevice(thisHandle);
  224.     }
  225.     
  226.     return (gBiggestDevice) ? (**(**gBiggestDevice).gdPMap).pixelSize : 1;
  227. }
  228.  
  229. short GetIndWindowDepth(short index)
  230. {
  231.     /* if Color Quickdraw is not available, the depth must be 1. */
  232.     /* if Color Quickdraw is available and the window exists, return the window's
  233.        GWorld's graphics device's pixel map's pixel depth */
  234.     /* if Color Quickdraw is available and the window does not exist, return the
  235.        pixel depth of the main screen */
  236.     return (gHasColorQD) ?
  237.                 (IndWindowExistsQQ(index) ?
  238.                     (**(**(GetGWorldDevice((GWorldPtr)GetIndOffscreenPtr(index)))).gdPMap).pixelSize :
  239.                     (**(**GetMainDevice()).gdPMap).pixelSize) :
  240.                 1;
  241. }
  242.  
  243. Boolean WindowIsColor(ExtendedWindowDataHandle theData)
  244. {
  245.     return (gHasColorQD) ?
  246.                 ((GetWindowDepth(theData)>8) ?
  247.                     TRUE :
  248.                     TestDeviceAttribute(GetGWorldDevice((GWorldPtr)GetOffscreenPtr(theData)),
  249.                         gdDevType)) :
  250.                 FALSE;
  251. }
  252.  
  253. void UpdateTheWindow(ExtendedWindowDataHandle theData)
  254. {
  255.     short            index;
  256.     long            offRowBytes, sizeOfOff;
  257.     unsigned long    updateResult;
  258.     Boolean            isColor;
  259.     PixMapHandle    thePixMapHandle;
  260.     GWorldPtr        currentGWorld;
  261.     GDHandle        currentGDHandle;
  262.     
  263.     index=GetWindowIndex(theData);
  264.     gBoundsRect[index]=GetIndWindowPtr(index)->portRect;
  265.     OffsetRect(&gBoundsRect[index], -gBoundsRect[index].left, -gBoundsRect[index].top);
  266.  
  267.     if (gHasColorQD)    /* w/o Color Quickdraw, GWorlds may not be supported */
  268.     {
  269.         if (gTheGWorld[index]==0L)        /* create new graphics world if none exists */
  270.         {
  271.             /* try to create new graphics world; display error if unsuccessful */
  272.             if (NewGWorld(&gTheGWorld[index],
  273.                 (GetBiggestDeviceDepth(theData)>=GetWindowData_maxDepth(theData)) ?
  274.                 (**theData).maxDepth : 0, &gBoundsRect[index], 0L, 0L, 0)!=0)
  275.             {
  276.                 HandleError(kNoMemory, TRUE);        /* quits */
  277.             }
  278.             
  279.             SetWindowData_windowDepth(theData, GetWindowDepth(theData));
  280.             NoPurgePixels(GetGWorldPixMap(gTheGWorld[index]));    /* never purge our pixmap! */
  281.             updateResult=1;
  282.         }
  283.         else updateResult=0;
  284.         
  285.         GetGWorld(¤tGWorld, ¤tGDHandle);    /* get current settings */
  286.         LockPixels(thePixMapHandle=GetGWorldPixMap(gTheGWorld[index]));    /* important!  copybits may move mem */
  287.         /* update offscreen graphics world, compensating for change in pixel depth */
  288.         updateResult|=(unsigned long)UpdateGWorld(&gTheGWorld[index],
  289.             (GetBiggestDeviceDepth(theData)>=GetWindowData_maxDepth(theData)) ?
  290.             GetWindowData_maxDepth(theData) : 0, &gBoundsRect[index], 0L, 0L, 0);
  291.         SetGWorld(gTheGWorld[index], 0L);                /* set to our offscreen gworld */
  292.         
  293.         isColor=WindowIsColor(theData);
  294.         if (isColor!=GetWindowData_isColor(theData))
  295.         {
  296.             SetWindowData_isColor(theData, isColor);
  297.             updateResult=1;
  298.         }
  299.         
  300.         if ((updateResult!=0L) || (GetWindowData_windowDepth(theData)!=GetWindowDepth(theData)))
  301.         {
  302.             SetWindowData_windowDepth(theData, GetWindowDepth(theData));
  303.             SetWindowData_offscreenNeedsUpdate(theData, TRUE);
  304.             CallDispatchProc(theData, kChangeDepth, 0L);
  305.         }
  306.     }
  307.     else    /* deal with (guaranteed) B/W bitmaps manually */
  308.     {
  309.         if (gBWGrafPtr[index]==0L)    /* create new offscreen bitmap if none exists */
  310.         {
  311.             gBWGrafPtr[index]=&gBWGrafPort[index];
  312.             OpenPort(gBWGrafPtr[index]);    /* make a new port */
  313.             
  314.             /* calculate the size of the offscreen bitmap from the boundsrect */
  315.             offRowBytes=(((gBoundsRect[index].right-gBoundsRect[index].left)+15)>>4)<<1;
  316.             sizeOfOff=(long)(gBoundsRect[index].bottom-gBoundsRect[index].top)*offRowBytes;
  317.             
  318.             gBWBitMap[index]=NewPtr(sizeOfOff);        /* allocate space for bitmap */
  319.             if (gBWBitMap[index]==0L)                /* abort if unsuccessful */
  320.             {
  321.                 ClosePort(gBWGrafPtr[index]);        /* cleaning up... */
  322.                 gBWGrafPtr[index]=0L;
  323.                 HandleError(kNoMemory, TRUE);        /* displaying error... */
  324.             }
  325.             
  326.             gBWGrafPort[index].portBits.baseAddr=gBWBitMap[index];    /* --> our bitmap */
  327.             gBWGrafPort[index].portBits.rowBytes=offRowBytes;        /* bitmap size */
  328.             gBWGrafPort[index].portBits.bounds=                        /* bitmap bounds */
  329.                 gBWGrafPort[index].portRect=gBoundsRect[index];
  330.             
  331.             SetPort(gBWGrafPtr[index]);
  332.             SetWindowData_offscreenNeedsUpdate(theData, TRUE);
  333.         }
  334.         else SetPort(gBWGrafPtr[index]);            /* set port for subsequent drawing */
  335.     }    
  336.     
  337.     if (GetWindowData_offscreenNeedsUpdate(theData))
  338.     {
  339.         SetWindowData_offscreenNeedsUpdate(theData, FALSE);
  340.         /* call window's dispatch and tell it to redraw itself */
  341.         CallDispatchProc(theData, kUpdate, GetWindowDepth((WindowDataHandle)theData));
  342.     }
  343.     
  344.     if (gHasColorQD)
  345.         SetGWorld(currentGWorld, currentGDHandle);    /* restore old settings */
  346.     
  347.     SetPort(GetWindowPtr(theData));
  348.     
  349.     /* copy offscreen bitmap from graphics world or bitmap to onscreen window */
  350.     if (CallDispatchProc(theData, kCopybits, (unsigned long)GetOffscreenPtr(theData))==kFailure)
  351.     {
  352.         CopyBits(    &(GetOffscreenPtr(theData)->portBits),
  353.                     &(GetWindowPtr(theData)->portBits),
  354.                     &gBoundsRect[index], &gBoundsRect[index], 0, 0L);
  355.     }
  356.     
  357.     for (index=0; index<MAX_TE_HANDLES; index++)
  358.     {
  359.         if (GetWindowData_hTE(theData, index)!=0L)
  360.         {
  361.             EraseRect(&(**GetWindowData_hTE(theData, index)).viewRect);
  362.             TEUpdate(&(GetWindowPtr(theData)->portRect),
  363.                         GetWindowData_hTE(theData, index));
  364.         }
  365.     }
  366.  
  367.     ValidRect(&(GetWindowPtr(theData)->portRect));    /* so we don't reupdate */
  368.     
  369.     if (gHasColorQD)
  370.         UnlockPixels(thePixMapHandle);    /* remember we locked these? */
  371.     
  372.     KillOffscreen(GetWindowIndex(theData));
  373. }
  374.  
  375. Boolean CloseTheWindow(ExtendedWindowDataHandle theData)
  376. {
  377.     /* if the window's dispatch cancels the close, abort */
  378.     if (CallDispatchProc(theData, kClose, 0L)==kCancel)
  379.         return FALSE;
  380.     
  381.     /* get rid of the actual window in memory */
  382.     DisposeWindow(GetWindowPtr(theData));
  383.     
  384.     /* set window pointer to 0L so we know it's gone */
  385.     SetWindowData_windowPtr(theData, 0L);
  386.     
  387.     /* kill offscreen bitmaps left over */
  388.     KillOffscreen(GetWindowIndex(theData));
  389.     
  390.     /* tell window's dispatch that it's disposed of now */
  391.     CallDispatchProc(theData, kDispose, 0L);
  392.     
  393.     return TRUE;    /* successful close */
  394. }
  395.  
  396. PicHandle DrawThePicture(PicHandle thePict, short whichPict, short x, short y)
  397. /* a standard routine for loading a picture (if necessary) and then drawing it */
  398. {
  399.     Rect            temp;
  400.     
  401.     if (thePict==0L)        /* get it if it doesn't exist */
  402.         thePict=(PicHandle)GetPicture(whichPict);
  403.     
  404.     HLock((Handle)thePict);        /* lock it down for dereferencing to get picture bounds */
  405.     temp.top=y;
  406.     temp.left=x;
  407.     temp.bottom=temp.top+(**thePict).picFrame.bottom-(**thePict).picFrame.top;
  408.     temp.right=temp.left+(**thePict).picFrame.right-(**thePict).picFrame.left;
  409.     DrawPicture(thePict, &temp);    /* draw picture at (x,y) */
  410.     HUnlock((Handle)thePict);        /* unlock for better memory management */
  411.     return thePict;
  412. }
  413.  
  414. PicHandle ReleaseThePict(PicHandle thePict)
  415. {
  416.     if (thePict!=0L)    /* if exists, release it */
  417.         ReleaseResource((Handle)thePict);
  418.     return 0L;
  419. }
  420.  
  421. short CallDispatchProc(ExtendedWindowDataHandle theData, short theMessage, unsigned long misc)
  422. {
  423.     return (GetWindowData_dispatchProc(theData))((WindowDataHandle)theData, theMessage, misc);
  424. }
  425.  
  426. void KillOffscreen(short index)
  427. {
  428.     if (gTheGWorld[index]!=0L)
  429.         DisposeGWorld(gTheGWorld[index]);
  430.     if (gBWGrafPtr[index]!=0L)
  431.         DisposePtr((Ptr)gBWGrafPtr[index]);
  432.     gTheGWorld[index]=0L;
  433.     gBWGrafPtr[index]=0L;
  434.     (**(gTheWindowData[index])).offscreenNeedsUpdate=TRUE;
  435.     CompactMem(maxSize);
  436. }
  437.  
  438. ExtendedWindowDataHandle GetWindowDataHandle(short index)
  439. {
  440.     return gTheWindowData[index];
  441. }
  442.  
  443. Point GetWindowBoundsTopLeft(WindowDataHandle theData)
  444. {
  445.     Point            tempPt;
  446.     Rect            tempRect;
  447.     
  448.     tempRect=GetWindowData_windowBounds(theData);
  449.     tempPt.h=tempRect.left;
  450.     tempPt.v=tempRect.top;
  451.     
  452.     return tempPt;
  453. }
  454.  
  455. GrafPtr GetOffscreenPtrFunction(WindowDataHandle theData)
  456. {
  457.     return (GrafPtr)(GetOffscreenPtr(theData));
  458. }
  459.